package com.dong.multithreading;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class CallableAndFuture {

    static class MyThread1 implements Callable<String> {
        private String key;

        public MyThread1(String key) {
            this.key = key;
        }

        @Override
        public String call() throws Exception {
            System.out.println("call start");
            Thread.sleep(3000);
            System.out.println("call over");
            return key;
        }
    }

    static class MyThread2 implements Runnable {
        @Override
        public void run() {
            System.out.println("run start");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("run over");
        }
    }

    @Test
    public void test1() throws Exception {
        String result = new MyThread1("1").call();
        System.out.println(result);
        new MyThread2().run();
    }

    @Test
    public void test2() throws Exception {
        ExecutorService threadPool = Executors.newFixedThreadPool(5);
        Future<String> future = threadPool.submit(new MyThread1("1"));
        threadPool.submit(new MyThread2());
        try {
            System.out.println(future.get());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }

    @Test
    public void test3() throws ExecutionException, InterruptedException {
        int taskSize = 100;
        //创建一个线程池
        ExecutorService pool = Executors.newFixedThreadPool(taskSize);
        // 创建多个有返回值的任务
        List<Future> list = new ArrayList<Future>();
        for (int i = 0; i < taskSize; i++) {
            Callable c = new MyThread1(i + " ");
            // 执行任务并获取 Future 对象
            Future f = pool.submit(c);
            list.add(f);
        }
        // 关闭线程池
        pool.shutdown();
        // 获取所有并发任务的运行结果
        for (Future f : list) {
            // 从 Future 对象上获取任务的返回值，并输出到控制台
            System.out.println("res：" + f.get().toString());
        }
    }

}
